﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.IO;

namespace TireService.EmailNotification
{
    public class EmailNotification
    {
        /// <summary>
        /// Function that generates string with html message about userlogin info
        /// </summary>
        /// <param name="CustomerName">Name on customer</param>
        /// <param name="UserName">User login name</param>
        /// <param name="Password">User login password</param>
        /// <returns>String with html message</returns>
        public string SendEmailUserInfoStandard(string CustomerName, string UserName, string Password)
        {
            Hashtable templateVars = new Hashtable();

            // Generate email message
            templateVars.Add("CustomerName", CustomerName);
            templateVars.Add("UserName", UserName);
            templateVars.Add("Password", Password);
            Parser parser = new Parser(EmailTemplates.Brugerlogin, templateVars, true);

            return parser.Parse();
        }

        /// <summary>
        /// Function that generates string with html message with voucher send from customer to a potential new customer
        /// </summary>
        /// <param name="CustomerName">Name on customer</param>
        /// <param name="CustomerMessage">Message from customer</param>
        /// <param name="Voucher">Voucher code</param>
        /// <returns>String with html message</returns>
        public string SendResellerQuotationCode(string CustomerName, string CustomerMessage, string Voucher)
        {
            Hashtable templateVars = new Hashtable();

            // Generate email message
            templateVars.Add("CustomerName", CustomerName);
            templateVars.Add("CustomerMessage", CustomerMessage);
            templateVars.Add("Voucher", Voucher);
            Parser parser = new Parser(EmailTemplates.Rabatkode, templateVars, true);

            return parser.Parse();
        }

        /// <summary>
        /// Function that generates string with html message to customer to finalize signup (Used in Interfaces where customer is created, but subscription/car is not)
        /// </summary>
        /// <param name="CustomerName">Name on customer</param>
        /// <param name="FinaliseSignup">Link for finalising order</param>
        /// <returns>String with html message</returns>
        public string SendFinaliseSignUpLink(string CustomerName, string FinaliseSignup)
        {
            Hashtable templateVars = new Hashtable();

            // Generate email message
            templateVars.Add("CustomerName", CustomerName);
            templateVars.Add("FinaliseSignup", FinaliseSignup);
            Parser parser = new Parser(EmailTemplates.BestillingBilData, templateVars, true);

            return parser.Parse();
        }

        /// <summary>
        /// Function that generates string with html message about customer booking link
        /// </summary>
        /// <param name="CustomerName">Name on customer</param>
        /// <param name="BookingLink">Link for booking</param>
        /// <returns>String with html message</returns>
        public string SendCustomerBookingLink(string CustomerName, string BookingLink)
        {
            Hashtable templateVars = new Hashtable();

            // Generate email message
            templateVars.Add("CustomerName", CustomerName);
            templateVars.Add("BookingLink", BookingLink);
            Parser parser = new Parser(EmailTemplates.BookingLink, templateVars, true);

            return parser.Parse();
        }

        /// <summary>
        /// Function that generates string with html message about customer subscription ordering confirmation
        /// </summary>
        /// <param name="CustomerName">Name of customer</param>
        /// <param name="CustomerId">Id on customer</param>
        /// <param name="InvoiceId">Invoice Id</param>
        /// <param name="PaymentAction">Integer with payment action</param>
        /// <param name="BookingLink">Link for online booking</param>
        /// <returns>String with html message</returns>
        public string SendCustomerSubscriptionOrderConfirmation(string CustomerName, string PaymentLink, string CustomerId, string InvoiceId, string PaymentAction, string BookingLink)
        //public string SendCustomerSubscriptionOrderConfirmation(string CustomerName, string SubscriptionNumber, int SubscriptionId)
        {
            Hashtable templateVars = new Hashtable();

            // Generate email message
            templateVars.Add("CustomerName", CustomerName);
            templateVars.Add("PaymentLink", string.Format("{0}?cid={1}&iid={2}&action={3}", PaymentLink, CustomerId, InvoiceId, PaymentAction));
            templateVars.Add("BookingLink", BookingLink);

            Parser parser = new Parser(EmailTemplates.Bestilling, templateVars, true);

            //if (SubscriptionId == 4)
            //{
            //    parser = new Parser(EmailTemplates.BestillingEnkeltHjulskift, templateVars);
            //}

            return parser.Parse();
        }

        /// <summary>
        /// Function that generates string with html message about customer invoice
        /// </summary>
        /// <param name="CustomerName">Name of customer</param>
        /// <param name="CustomerId">Id on customer</param>
        /// <param name="InvoiceId">Invoice Id</param>
        /// <param name="PaymentAction">Integer with payment action</param>
        /// <returns>String with html message</returns>
        public string SendCustomerInvoice(string CustomerName, string PaymentLink, string CustomerId, string InvoiceId, string PaymentAction)
        {
            Hashtable templateVars = new Hashtable();

            // Generate email message
            templateVars.Add("CustomerName", CustomerName);
            templateVars.Add("PaymentLink", string.Format("{0}?cid={1}&iid={2}&action={3}", PaymentLink, CustomerId, InvoiceId, PaymentAction));

            Parser parser = new Parser(EmailTemplates.Faktura, templateVars, true);

            return parser.Parse();
        }

        /// <summary>
        /// Function that generates string with html message about customer invoice reminder
        /// </summary>
        /// <param name="CustomerName">Name of customer</param>
        /// <param name="CustomerId">Id on customer</param>
        /// <param name="InvoiceId">Invoice Id</param>
        /// <param name="PaymentAction">Integer with payment action</param>
        /// <returns>String with html message</returns>
        public string SendCustomerInvoiceReminder(string CustomerName, string PaymentLink, string CustomerId, string InvoiceId, string PaymentAction)
        {
            Hashtable templateVars = new Hashtable();

            // Generate email message
            templateVars.Add("CustomerName", CustomerName);
            templateVars.Add("PaymentLink", string.Format("{0}?cid={1}&iid={2}&action={3}", PaymentLink, CustomerId, InvoiceId, PaymentAction));

            Parser parser = new Parser(EmailTemplates.FakturaPaamindelse, templateVars, true);

            return parser.Parse();
        }

        /// <summary>
        /// Function that generates string with html message about customer subscription renewal ordering confirmation
        /// </summary>
        /// <param name="CustomerName">Name of customer</param>
        /// <param name="SubscriptionNumber">Number on subscription</param>
        /// <param name="CustomerId">Id on customer</param>
        /// <param name="InvoiceId">Id on Invoice</param>
        /// <param name="PaymentAction">PaymentAction</param>
        /// <returns>String with html message</returns>
        public string SendCustomerSubscriptionRenewalOrderConfirmation(string CustomerName, string SubscriptionNumber, string PaymentLink, string CustomerId, string InvoiceId, string PaymentAction)
        {
            Hashtable templateVars = new Hashtable();

            // Generate email message
            templateVars.Add("CustomerName", CustomerName);
            templateVars.Add("SubscriptionNumber", SubscriptionNumber);
            templateVars.Add("PaymentLink", string.Format("{0}?cid={1}&iid={2}&action={3}", PaymentLink, CustomerId, InvoiceId, PaymentAction));
            
            Parser parser = new Parser(EmailTemplates.Fornyelse, templateVars, true);

            return parser.Parse();
        }

        /// <summary>
        /// Function that generates string with html message with confirmation on customer selfservice booking
        /// </summary>
        /// <param name="CustomerName"></param>
        /// <param name="ScheduleDate"></param>
        /// <param name="TimeSpanValue"></param>
        /// <param name="Address"></param>
        /// <param name="ZipCode"></param>
        /// <param name="City"></param>
        /// <returns></returns>
        public string SendConfirmationOnSelfServiceBookingSchedule(string CustomerName, string ScheduleDate, string TimeSpanValue, string Address, string ZipCode, string City, string ServiceComments)
        {
            Hashtable templateVars = new Hashtable();

            // Generate email message
            templateVars.Add("CustomerName", CustomerName);
            templateVars.Add("ScheduleDate", ScheduleDate);
            templateVars.Add("TimeSpanValue", TimeSpanValue);
            templateVars.Add("Address", Address);
            templateVars.Add("ZipCode", ZipCode);
            templateVars.Add("City", City);
            templateVars.Add("ServiceComments", ServiceComments);
            Parser parser = new Parser(EmailTemplates.BookingAfTid, templateVars, true);

            return parser.Parse();
        }

        /// <summary>
        /// Function that generates string with html message with confirmation on customer selfservice booking
        /// </summary>
        /// <param name="CustomerName"></param>
        /// <param name="ScheduleDate"></param>
        /// <param name="TimeSpanValue"></param>
        /// <param name="Address"></param>
        /// <param name="ZipCode"></param>
        /// <param name="City"></param>
        /// <returns></returns>
        public string SendReminderBookingSchedule(string CustomerName, string ScheduleDate, string TimeSpanValue, string Address, string ZipCode, string City, string ServiceComments)
        {
            Hashtable templateVars = new Hashtable();

            // Generate email message
            templateVars.Add("CustomerName", CustomerName);
            templateVars.Add("ScheduleDate", ScheduleDate);
            templateVars.Add("TimeSpanValue", TimeSpanValue);
            templateVars.Add("Address", Address);
            templateVars.Add("ZipCode", ZipCode);
            templateVars.Add("City", City);
            templateVars.Add("ServiceComments", ServiceComments);
            Parser parser = new Parser(EmailTemplates.PaamindelseBookingAfTid, templateVars, true);

            return parser.Parse();
        }

        // Udkommenteret d. 24/2-2013 (vil måske kun bruge bookaftid.htm istedet)
        ///// <summary>
        ///// Function that generates string with html message confirmation on service booking time
        ///// </summary>
        ///// <param name="CustomerName"></param>
        ///// <param name="ScheduleDate"></param>
        ///// <param name="TimeSpanValue"></param>
        ///// <param name="Address"></param>
        ///// <param name="ZipCode"></param>
        ///// <param name="City"></param>
        ///// <returns></returns>
        //public string SendConfirmationOnBookingSchedule(string CustomerName, string ScheduleDate, string TimeSpanValue, string Address, string ZipCode, string City)
        //{
        //    Hashtable templateVars = new Hashtable();

        //    // Generate email message
        //    templateVars.Add("CustomerName", CustomerName);
        //    templateVars.Add("ScheduleDate", ScheduleDate);
        //    templateVars.Add("TimeSpanValue", TimeSpanValue);
        //    templateVars.Add("Address", Address);
        //    templateVars.Add("ZipCode", ZipCode);
        //    templateVars.Add("City", City);
        //    Parser parser = new Parser(EmailTemplates.TidBekraeftet, templateVars, true);

        //    return parser.Parse();
        //}

        /// <summary>
        /// Function that generates string with html message with details on tireset pattern
        /// </summary>
        /// <param name="CustomerName"></param>
        /// <param name="TireSetType"></param>
        /// <param name="RegistrationNumber"></param>
        /// <param name="RightFront"></param>
        /// <param name="LeftFront"></param>
        /// <param name="RightBack"></param>
        /// <param name="LeftBack"></param>
        /// <returns></returns>
        public string SendTireSetPattern(string CustomerName, string TireSetType, string RegistrationNumber, string RightFront, string LeftFront, string RightBack, string LeftBack)
        {
            Hashtable templateVars = new Hashtable();

            // Generate email message
            templateVars.Add("CustomerName", CustomerName);
            templateVars.Add("TireSetType", TireSetType);
            templateVars.Add("RegistrationNumber", RegistrationNumber);
            templateVars.Add("RightFront", RightFront);
            templateVars.Add("LeftFront", LeftFront);
            templateVars.Add("RightBack", RightBack);
            templateVars.Add("LeftBack", LeftBack);
            Parser parser = new Parser(EmailTemplates.Daekmoenster, templateVars, true);

            return parser.Parse();
        }

        /// <summary>
        /// Function that generates string with html message for customer with suggestion for booking on service
        /// </summary>
        /// <param name="CustomerName"></param>
        /// <param name="RegistrationNumber"></param>
        /// <param name="TireSetType"></param>
        /// <param name="ScheduleDate"></param>
        /// <param name="TimeSpan"></param>
        /// <param name="Address"></param>
        /// <param name="ZipCode"></param>
        /// <param name="City"></param>
        /// <param name="CustomerApprovalLink"></param>
        /// <param name="CustomerDisapprovalLink"></param>
        /// <returns></returns>
        public string SendServiceCarScheduleDetailBooking(string CustomerName, string RegistrationNumber, string TireSetType, string ScheduleDate, string TimeSpan, string Address, string ZipCode, string City, string CustomerApprovalLink, string CustomerDisapprovalLink)
        {
            Hashtable templateVars = new Hashtable();

            // Generate email message
            templateVars.Add("CustomerName", CustomerName);
            templateVars.Add("RegistrationNumber", RegistrationNumber);
            templateVars.Add("TireSetType", TireSetType);
            templateVars.Add("ScheduleDate", ScheduleDate);
            templateVars.Add("TimeSpan", TimeSpan);
            templateVars.Add("Address", Address);
            templateVars.Add("ZipCode", ZipCode);
            templateVars.Add("City", City);
            templateVars.Add("CustomerApprovalLink", CustomerApprovalLink);
            templateVars.Add("CustomerDisapprovalLink", CustomerDisapprovalLink);
            Parser parser = new Parser(EmailTemplates.Hjulskift_Booking, templateVars, true);

            return parser.Parse();
        }

        /// <summary>
        /// Function that generates string with html message for customer with confirmation on completed service on their car
        /// </summary>
        /// <param name="CustomerName"></param>
        /// <param name="ServiceDone"></param>
        /// <param name="ScheduleDate"></param>
        /// <returns></returns>
        public string SendServiceCompletionCustomerNotification(string CustomerName, string ServiceDone, string ScheduleDate) 
        {
            Hashtable templateVars = new Hashtable();

            // Generate email message
            templateVars.Add("CustomerName", CustomerName);
            templateVars.Add("ScheduleDate", ScheduleDate);
            templateVars.Add("ServiceDone", ServiceDone);
            Parser parser = new Parser(EmailTemplates.ServiceCompleted, templateVars, true);

            return parser.Parse();
        }

        /// <summary>
        /// Function that generates string with html message for customer with confirmation on completed service on their car
        /// </summary>
        /// <param name="CustomerName"></param>
        /// <param name="ServiceDone"></param>
        /// <param name="ScheduleDate"></param>
        /// <param name="CustomerFeedbackURL"></param>
        /// <returns></returns>
        public string SendServiceCompletionCustomerNotificationPlusReview(string CustomerName, string ServiceDone, string ScheduleDate, string CustomerFeedbackURL)
        {
            Hashtable templateVars = new Hashtable();

            // Generate email message
            templateVars.Add("CustomerName", CustomerName);
            templateVars.Add("FeedBackLink", CustomerFeedbackURL);
            templateVars.Add("ScheduleDate", ScheduleDate);
            templateVars.Add("ServiceDone", ServiceDone);
            Parser parser = new Parser(EmailTemplates.ServiceCompletedPlusReview, templateVars, true);

            return parser.Parse();
        }

        /// <summary>
        /// Function that generates string with html message for customer with confirmation on deactivated subscription and car
        /// </summary>
        /// <param name="CustomerName"></param>
        /// <param name="SubscriptionNumber"></param>
        /// <param name="RegistrationNumber"></param>
        /// <param name="TireSetActionText"></param>
        /// <returns></returns>
        public string SendSubscriptionDeactivationCustomerNotification(string CustomerName, string SubscriptionNumber, string RegistrationNumber, string TireSetActionText)
        {
            Hashtable templateVars = new Hashtable();

            // Generate email message
            templateVars.Add("CustomerName", CustomerName);
            templateVars.Add("SubscriptionNumber", SubscriptionNumber);
            templateVars.Add("RegistrationNumber", RegistrationNumber);
            templateVars.Add("TireSetActionText", TireSetActionText);
            Parser parser = new Parser(EmailTemplates.Deaktivering, templateVars, true);

            return parser.Parse();
        }

        /// <summary>
        /// Function that generates string with html message for customer with confirmation on replacement of car with a new car
        /// </summary>
        /// <param name="CustomerName"></param>
        /// <param name="SubscriptionNumber"></param>
        /// <param name="RegistrationNumberOld"></param>
        /// <param name="RegistrationNumber"></param>
        /// <param name="TireSetActionText"></param>
        /// <returns></returns>
        public string SendReplaceCarCustomerNotification(string CustomerName, string SubscriptionNumber, string RegistrationNumberOld, string RegistrationNumber, string TireSetActionText)
        {
            Hashtable templateVars = new Hashtable();

            // Generate email message
            templateVars.Add("CustomerName", CustomerName);
            templateVars.Add("SubscriptionNumber", SubscriptionNumber);
            templateVars.Add("RegistrationNumberOld", RegistrationNumberOld);
            templateVars.Add("RegistrationNumber", RegistrationNumber);
            templateVars.Add("TireSetActionText", TireSetActionText);
            Parser parser = new Parser(EmailTemplates.UdskiftBil, templateVars, true);

            return parser.Parse();
        }

        /// <summary>
        /// Function that generates string with html message for customer with confirmation creation of subscription and car
        /// </summary>
        /// <param name="CustomerName"></param>
        /// <param name="SubscriptionNumber"></param>
        /// <param name="RegistrationNumber"></param>
        /// <param name="TireSetActionText"></param>
        /// <returns></returns>
        public string SendCreateSubscriptionAndCarCustomerNotification(string CustomerName, string SubscriptionNumber, string RegistrationNumber, string TireSetActionText)
        {
            Hashtable templateVars = new Hashtable();

            // Generate email message
            templateVars.Add("CustomerName", CustomerName);
            templateVars.Add("SubscriptionNumber", SubscriptionNumber);
            templateVars.Add("RegistrationNumber", RegistrationNumber);
            templateVars.Add("TireSetActionText", TireSetActionText);
            Parser parser = new Parser(EmailTemplates.OprettelseAbonnementBil, templateVars, true);

            return parser.Parse();
        }

        public string SendTireQuotation(string CustomerName, string RegistrationNumber, string TireTypeDescription, string Note, string HF, string VF, string HB, string VB, string TireTreadRecommendedChange, string AcceptLink, string RejectLink, string TireDescription, string Quantity, string TirePriceExVat, string TirePriceTotalExVat, string MontPriceExVat, string MontPriceTotalExVat, string TotalExVat, string TotalVat, string Total, string ExpireDetails)
        {
            Hashtable templateVars = new Hashtable();

            // Generate email message
            templateVars.Add("CustomerName", CustomerName);
            templateVars.Add("RegistrationNumber", RegistrationNumber);
            templateVars.Add("TireTypeDescription", TireTypeDescription);
            templateVars.Add("Note", Note);
            templateVars.Add("HF", HF);
            templateVars.Add("VF", VF);
            templateVars.Add("HB", HB);
            templateVars.Add("VB", VB);
            templateVars.Add("TireTreadRecommendedChange", TireTreadRecommendedChange);
            templateVars.Add("AcceptLink", AcceptLink);
            templateVars.Add("RejectLink", RejectLink);
            templateVars.Add("TireDescription", TireDescription);
            templateVars.Add("Quantity", Quantity);
            templateVars.Add("TirePriceExVat", TirePriceExVat);
            templateVars.Add("TirePriceTotalExVat", TirePriceTotalExVat);
            templateVars.Add("MontPriceExVat", MontPriceExVat);
            templateVars.Add("MontPriceTotalExVat", MontPriceTotalExVat);
            templateVars.Add("TotalExVat", TotalExVat);
            templateVars.Add("TotalVat", TotalVat);
            templateVars.Add("Total", Total);
            templateVars.Add("ExpireDetails", ExpireDetails);
            Parser parser = new Parser(EmailTemplates.TilbudDaek, templateVars, true);

            return parser.Parse();
        }

        // Temp email solutions for tirequotations (2013-03-03)
        public string SendTireQuotation(string CustomerName, string RegistrationNumber, string Note, string HF, string VF, string HB, string VB, string AcceptLink, string RejectLink, string TireDescription, string Qty, string TirePriceExVat, string TirePriceTotalExVat, string EnvPriceTotalExVat, string MontPriceExVat, string MontPriceTotalExVat, string TotalExVat, string TotalVat, string Total)
        {
            Hashtable templateVars = new Hashtable();

            // Generate email message
            templateVars.Add("CustomerName", CustomerName);
            templateVars.Add("RegistrationNumber", RegistrationNumber);
            templateVars.Add("Note", Note);
            templateVars.Add("HF", HF);
            templateVars.Add("VF", VF);
            templateVars.Add("HB", HB);
            templateVars.Add("VB", VB);
            templateVars.Add("AcceptLink", AcceptLink);
            templateVars.Add("RejectLink", RejectLink);
            templateVars.Add("TireDescription", TireDescription);
            templateVars.Add("Qty", Qty);
            templateVars.Add("TirePriceExVat", TirePriceExVat);
            templateVars.Add("TirePriceTotalExVat", TirePriceTotalExVat);
            templateVars.Add("EnvPriceTotalExVat", EnvPriceTotalExVat);
            templateVars.Add("MontPriceExVat", MontPriceExVat);
            templateVars.Add("MontPriceTotalExVat", MontPriceTotalExVat);
            templateVars.Add("TotalExVat", TotalExVat);
            templateVars.Add("TotalVat", TotalVat);
            templateVars.Add("Total", Total);
            Parser parser = new Parser(EmailTemplates.TilbudDaek, templateVars, true);

            return parser.Parse();
        }

        public string SendTireQuotationAccept(string CustomerName, string RegistrationNumber, string TireDescription, string Qty, string TirePriceExVat, string TirePriceTotalExVat, string EnvPriceTotalExVat, string MontPriceExVat, string MontPriceTotalExVat, string TotalExVat, string TotalVat, string Total)
        {
            Hashtable templateVars = new Hashtable();

            // Generate email message
            templateVars.Add("CustomerName", CustomerName);
            templateVars.Add("RegistrationNumber", RegistrationNumber);
            templateVars.Add("TireDescription", TireDescription);
            templateVars.Add("Qty", Qty);
            templateVars.Add("TirePriceExVat", TirePriceExVat);
            templateVars.Add("TirePriceTotalExVat", TirePriceTotalExVat);
            templateVars.Add("EnvPriceTotalExVat", EnvPriceTotalExVat);
            templateVars.Add("MontPriceExVat", MontPriceExVat);
            templateVars.Add("MontPriceTotalExVat", MontPriceTotalExVat);
            templateVars.Add("TotalExVat", TotalExVat);
            templateVars.Add("TotalVat", TotalVat);
            templateVars.Add("Total", Total);
            Parser parser = new Parser(EmailTemplates.TilbudDaekAccepteret, templateVars, true);

            return parser.Parse();
        }

        public string SendTireQuotationReject(string CustomerName, string RegistrationNumber, string TireDescription, string Qty, string TirePriceExVat, string TirePriceTotalExVat, string EnvPriceTotalExVat, string MontPriceExVat, string MontPriceTotalExVat, string TotalExVat, string TotalVat, string Total)
        {
            Hashtable templateVars = new Hashtable();

            // Generate email message
            templateVars.Add("CustomerName", CustomerName);
            templateVars.Add("RegistrationNumber", RegistrationNumber);
            templateVars.Add("TireDescription", TireDescription);
            templateVars.Add("Qty", Qty);
            templateVars.Add("TirePriceExVat", TirePriceExVat);
            templateVars.Add("TirePriceTotalExVat", TirePriceTotalExVat);
            templateVars.Add("EnvPriceTotalExVat", EnvPriceTotalExVat);
            templateVars.Add("MontPriceExVat", MontPriceExVat);
            templateVars.Add("MontPriceTotalExVat", MontPriceTotalExVat);
            templateVars.Add("TotalExVat", TotalExVat);
            templateVars.Add("TotalVat", TotalVat);
            templateVars.Add("Total", Total);
            Parser parser = new Parser(EmailTemplates.TilbudDaekAfvist, templateVars, true);

            return parser.Parse();
        }


        #region Shared Classes




        /// <remarks>
        /// Template Parser is simple parser has been written on C#.
        /// It allows setup variables and conditions block in template.
        /// Also you can use some of variable's modificators.
        ///
        ///     Author: Alexander Kleshevnikov
        ///     E-mail: seigo@icconline.com
        ///
        /// <example>There is the simpl example of template for html page:
        /// <code>
        /// <html>
        /// <head><title>##Title##</title></head>
        /// <body><h1>##Title:upper##</h1>
        /// ##If--IsRegisteredUser##
        /// Hello, ##UserName##!
        /// ##Else--IsRegisteredUser##
        /// Please sign in.
        /// ##EndIf--IsRegisteredUser##
        /// </body>
        /// </html>
        /// </code>
        /// To parse this template you can use the following code:
        /// <code>
        /// ...
        /// Hashtable Variables = new Hashtable();
        /// Variables.Add("Title", "Login In");
        /// Variables.Add("IsRegisteredUser", true);
        /// Variables.Add("UserName", "seigo");
        /// TemplateParser tpl = new TemplateParser("template.htm", Variables);
        /// tpl.ParseToFile("result.htm");
        /// ...
        /// </code>
        /// </example>
        /// </remarks>
        public class Parser
        {
            private string _strTemplateBlock;
            private Hashtable _hstValues;
            private Hashtable _ErrorMessage = new Hashtable();
            private string _ParsedBlock;

            private Dictionary<string, Parser> _Blocks = new Dictionary<string, Parser>();

            private string VariableTagBegin = "##";
            private string VariableTagEnd = "##";

            private string ModificatorTag = ":";
            private string ModificatorParamSep = ",";

            private string ConditionTagIfBegin = "##If--";
            private string ConditionTagIfEnd = "##";
            private string ConditionTagElseBegin = "##Else--";
            private string ConditionTagElseEnd = "##";
            private string ConditionTagEndIfBegin = "##EndIf--";
            private string ConditionTagEndIfEnd = "##";

            private string BlockTagBeginBegin = "##BlockBegin--";
            private string BlockTagBeginEnd = "##";
            private string BlockTagEndBegin = "##BlockEnd--";
            private string BlockTagEndEnd = "##";

            /// <value>Template block</value>
            public string TemplateBlock
            {
                get { return this._strTemplateBlock; }
                set
                {
                    this._strTemplateBlock = value;
                    ParseBlocks();
                }
            }

            /// <value>Template Variables</value>
            public Hashtable Variables
            {
                get { return this._hstValues; }
                set { this._hstValues = value; }
            }

            /// <value>Error Massage</value>
            public Hashtable ErrorMessage
            {
                get { return _ErrorMessage; }
            }

            /// <value>Blocks inside template</value>
            public Dictionary<string, Parser> Blocks
            {
                get { return _Blocks; }
            }

            /// <summary>
            /// Creates a new instance of TemplateParser
            /// </summary>

            #region Contructors
            public Parser()
            {
                this._strTemplateBlock = "";
            }

            public Parser(string FilePath)
            {
                ReadTemplateFromFile(FilePath);
                ParseBlocks();
            }

            public Parser(Hashtable Variables)
            {
                this._hstValues = Variables;
            }

            public Parser(string FilePath, Hashtable Variables)
            {
                ReadTemplateFromFile(FilePath);
                this._hstValues = Variables;
                ParseBlocks();
            }

            public Parser(string FileContent, Hashtable Variables, bool FileContentHTML)
            {
                this.TemplateBlock = FileContent;
                this._hstValues = Variables;
                ParseBlocks();
            }

            #endregion

            /// <summary>
            /// Setup template from specified file
            /// </summary>
            /// <param name="FilePath">Full phisical path to template file</param>
            public void SetTemplateFromFile(string FilePath)
            {
                ReadTemplateFromFile(FilePath);
            }

            /// <summary>
            /// Setup template as string block
            /// </summary>
            /// <param name="TemplateBlock">String template block</param>
            public void SetTemplate(string TemplateBlock)
            {
                this.TemplateBlock = TemplateBlock;
            }

            /// <summary>
            /// Parse template after setuping Template and Variables
            /// </summary>
            /// <returns>
            /// Parsed Block for Whole Template
            /// </returns>
            public string Parse()
            {
                ParseConditions();
                ParseVariables();
                return this._ParsedBlock;
            }

            /// <summary>
            /// Parse Template Block
            /// </summary>
            /// <returns>
            /// Parsed Block for Specified BlockName
            /// </returns>
            public string ParseBlock(string BlockName, Hashtable Variables)
            {
                if (!this._Blocks.ContainsKey(BlockName))
                {
                    throw new ArgumentException(String.Format("Could not find Block with Name '{0}'", BlockName));
                }

                this._Blocks[BlockName].Variables = Variables;
                return this._Blocks[BlockName].Parse();
            }

            /// <summary>
            /// Parse template and save result into specified file
            /// </summary>
            /// <param name="FilePath">Full physical path to file</param>
            /// <param name="ReplaceIfExists">If true file which already exists
            /// will be replaced</param>
            /// <returns>True if new content has been written</returns>
            public bool ParseToFile(string FilePath, bool ReplaceIfExists)
            {
                if (File.Exists(FilePath) && !ReplaceIfExists)
                {
                    return false;
                }
                else
                {
                    StreamWriter sr = File.CreateText(FilePath);
                    sr.Write(Parse());
                    sr.Close();
                    return true;
                }
            }

            /// <summary>
            /// Read template content from specified file
            /// </summary>
            /// <param name="FilePath">Full physical path to template file</param>
            private void ReadTemplateFromFile(string FilePath)
            {
                if (!File.Exists(FilePath))
                {
                    throw new ArgumentException("Template file does not exist.");
                }

                StreamReader reader = new StreamReader(FilePath);
                this.TemplateBlock = reader.ReadToEnd();
                reader.Close();
            }

            /// <summary>
            /// Parse all blocks in template
            /// </summary>
            private void ParseBlocks()
            {
                //int idxPrevious = 0;
                int idxCurrent = 0;
                while ((idxCurrent = this._strTemplateBlock.IndexOf(this.BlockTagBeginBegin, idxCurrent)) != -1)
                {
                    string BlockName;
                    int idxBlockBeginBegin, idxBlockBeginEnd, idxBlockEndBegin;

                    idxBlockBeginBegin = idxCurrent;
                    idxCurrent += this.BlockTagBeginBegin.Length;

                    // Searching for BlockBeginEnd Index

                    idxBlockBeginEnd = this._strTemplateBlock.IndexOf(this.BlockTagBeginEnd, idxCurrent);
                    if (idxBlockBeginEnd == -1) throw new Exception("Could not find BlockTagBeginEnd");

                    // Getting Block Name

                    BlockName = this._strTemplateBlock.Substring(idxCurrent, (idxBlockBeginEnd - idxCurrent));
                    idxCurrent = idxBlockBeginEnd + this.BlockTagBeginEnd.Length;

                    // Getting End of Block index

                    string EndBlockStatment = this.BlockTagEndBegin + BlockName + this.BlockTagEndEnd;
                    idxBlockEndBegin = this._strTemplateBlock.IndexOf(EndBlockStatment, idxCurrent);
                    if (idxBlockEndBegin == -1) throw new Exception("Could not find End of Block with name '" + BlockName + "'");

                    // Add Block to Dictionary

                    Parser block = new Parser();
                    block.TemplateBlock = this._strTemplateBlock.Substring(idxCurrent, (idxBlockEndBegin - idxCurrent));
                    this._Blocks.Add(BlockName, block);

                    // Remove Block Declaration From Template

                    this._strTemplateBlock = this._strTemplateBlock.Remove(idxBlockBeginBegin, (idxBlockEndBegin - idxBlockBeginBegin));

                    idxCurrent = idxBlockBeginBegin;
                }
            }

            /// <summary>
            /// Parse all conditions in template
            /// </summary>
            private void ParseConditions()
            {
                int idxPrevious = 0;
                int idxCurrent = 0;
                this._ParsedBlock = "";
                while ((idxCurrent = this._strTemplateBlock.IndexOf(this.ConditionTagIfBegin, idxCurrent)) != -1)
                {
                    string VarName;
                    string TrueBlock, FalseBlock;
                    string ElseStatment, EndIfStatment;
                    int idxIfBegin, idxIfEnd, idxElseBegin, idxEndIfBegin;
                    bool boolValue;

                    idxIfBegin = idxCurrent;
                    idxCurrent += this.ConditionTagIfBegin.Length;

                    // Searching for EndIf Index

                    idxIfEnd = this._strTemplateBlock.IndexOf(this.ConditionTagIfEnd, idxCurrent);
                    if (idxIfEnd == -1) throw new Exception("Could not find ConditionTagIfEnd");

                    // Getting Value Name

                    VarName = this._strTemplateBlock.Substring(idxCurrent, (idxIfEnd - idxCurrent));

                    idxCurrent = idxIfEnd + this.ConditionTagIfEnd.Length;

                    // Compare ElseIf and EndIf Indexes

                    ElseStatment = this.ConditionTagElseBegin + VarName + this.ConditionTagElseEnd;
                    EndIfStatment = this.ConditionTagEndIfBegin + VarName + this.ConditionTagEndIfEnd;
                    idxElseBegin = this._strTemplateBlock.IndexOf(ElseStatment, idxCurrent);
                    idxEndIfBegin = this._strTemplateBlock.IndexOf(EndIfStatment, idxCurrent);
                    if (idxElseBegin > idxEndIfBegin) throw new Exception("Condition Else Tag placed after Condition Tag EndIf for '" + VarName + "'");

                    // Getting True and False Condition Blocks

                    if (idxElseBegin != -1)
                    {
                        TrueBlock = this._strTemplateBlock.Substring(idxCurrent, (idxElseBegin - idxCurrent));
                        FalseBlock = this._strTemplateBlock.Substring((idxElseBegin + ElseStatment.Length), (idxEndIfBegin - idxElseBegin - ElseStatment.Length));
                    }
                    else
                    {
                        TrueBlock = this._strTemplateBlock.Substring(idxCurrent, (idxEndIfBegin - idxCurrent));
                        FalseBlock = "";
                    }

                    // Parse Condition

                    try
                    {
                        boolValue = Convert.ToBoolean(this._hstValues[VarName]);
                    }
                    catch
                    {
                        boolValue = false;
                    }

                    string BeforeBlock = this._strTemplateBlock.Substring(idxPrevious, (idxIfBegin - idxPrevious));

                    if (this._hstValues.ContainsKey(VarName) && boolValue)
                    {
                        this._ParsedBlock += BeforeBlock + TrueBlock.Trim();
                    }
                    else
                    {
                        this._ParsedBlock += BeforeBlock + FalseBlock.Trim();
                    }

                    idxCurrent = idxEndIfBegin + EndIfStatment.Length;
                    idxPrevious = idxCurrent;
                }
                this._ParsedBlock += this._strTemplateBlock.Substring(idxPrevious);
            }

            /// <summary>
            /// Parse all variables in template
            /// </summary>
            private void ParseVariables()
            {
                int idxCurrent = 0;
                while ((idxCurrent = this._ParsedBlock.IndexOf(this.VariableTagBegin, idxCurrent)) != -1)
                {
                    string VarName, VarValue;
                    int idxVarTagEnd;

                    idxVarTagEnd = this._ParsedBlock.IndexOf(this.VariableTagEnd, (idxCurrent + this.VariableTagBegin.Length));
                    if (idxVarTagEnd == -1) throw new Exception(String.Format("Index {0}: could not find Variable End Tag", idxCurrent));

                    // Getting Variable Name

                    VarName = this._ParsedBlock.Substring((idxCurrent + this.VariableTagBegin.Length), (idxVarTagEnd - idxCurrent - this.VariableTagBegin.Length));

                    // Checking for Modificators

                    string[] VarParts = VarName.Split(this.ModificatorTag.ToCharArray());
                    VarName = VarParts[0];

                    // Getting Variable Value
                    // If Variable doesn't exist in _hstValue then
                    // Variable Value equal empty string

                    // [added 6/6/2006] If variable is null than it will also has empty string

                    VarValue = String.Empty;
                    if (this._hstValues.ContainsKey(VarName) && this._hstValues[VarName] != null)
                    {
                        VarValue = this._hstValues[VarName].ToString();
                    }

                    // Apply All Modificators to Variable Value

                    for (int i = 1; i < VarParts.Length; i++)
                        this.ApplyModificator(ref VarValue, VarParts[i]);

                    // Replace Variable in Template

                    this._ParsedBlock = this._ParsedBlock.Substring(0, idxCurrent) + VarValue + this._ParsedBlock.Substring(idxVarTagEnd + this.VariableTagEnd.Length);

                    // Add Length of added value to Current index 
                    // to prevent looking for variables in the added value
                    // Fixed Date: April 5, 2006
                    idxCurrent += VarValue.Length;
                }
            }

            /// <summary>
            /// Method for applying modificators to variable value
            /// </summary>
            /// <param name="Value">Variable value</param>
            /// <param name="Modificator">Determination statment</param>
            private void ApplyModificator(ref string Value, string Modificator)
            {
                // Checking for parameters

                string strModificatorName = "";
                string strParameters = "";
                int idxStartBrackets, idxEndBrackets;
                if ((idxStartBrackets = Modificator.IndexOf("(")) != -1)
                {
                    idxEndBrackets = Modificator.IndexOf(")", idxStartBrackets);
                    if (idxEndBrackets == -1)
                    {
                        throw new Exception("Incorrect modificator expression");
                    }
                    else
                    {
                        strModificatorName = Modificator.Substring(0, idxStartBrackets).ToUpper();
                        strParameters = Modificator.Substring(idxStartBrackets + 1, (idxEndBrackets - idxStartBrackets - 1));
                    }
                }
                else
                {
                    strModificatorName = Modificator.ToUpper();
                }
                string[] arrParameters = strParameters.Split(this.ModificatorParamSep.ToCharArray());
                for (int i = 0; i < arrParameters.Length; i++)
                    arrParameters[i] = arrParameters[i].Trim();

                try
                {
                    Type typeModificator = Type.GetType("TemplateParser.Modificators." + strModificatorName);
                    if (typeModificator.IsSubclassOf(Type.GetType("TemplateParser.Modificators.Modificator")))
                    {

                        Modificator objModificator = (Modificator)Activator.CreateInstance(typeModificator);
                        objModificator.Apply(ref Value, arrParameters);
                    }
                }
                catch
                {
                    throw new Exception(String.Format("Could not find modificator '{0}'", strModificatorName));
                }
            }
        }

        #endregion
    }
}
